//
//  JDNetworkManager.swift
//  DragonWallet
//
//  Created by volantPig on 2023/12/26.
//

import UIKit
import Moya
import Alamofire

// 成功回调
typealias successDataClosure = (Data) -> Void;

// 成功回调
typealias successClosure = (String) -> Void;
// 失败回调
typealias failClosure = (MoyaError) -> Void;
// 错误回调
typealias erroeClosure = (Int) -> Void;

let endPointClosure = { (target: JDApi) -> Endpoint in
    
    // 拿到 完整 路径
    var url = target.baseURL.absoluteString + target.path;
    var task = target.task;
    
    var endPoint = Endpoint.init(url: url, sampleResponseClosure: { () -> EndpointSampleResponse in
        return EndpointSampleResponse.networkResponse(200, target.sampleData)
    }, method: target.method, task: task, httpHeaderFields: target.headers)
    
    return endPoint.adding(newHTTPHeaderFields: [
        "Content-type" : "application/json",
        "Accept" : "application/json, text/plain, */*",
//        "Authorization": "Basic aDVfYzpoNV9jX3NlY3JldA==",//String.init(format: "Basic %@", "ios_c:ios_c_secret".base64Encoding()),
//        "Tenant-Id": "000000"//,
//        "Blade-Auth": ""//WJBTokenModel.default.sessionId ?? "" //WJBConfigManager.wjbConfigManager.userInfoDic.sessionId ?? "" //"bearer eyJ0eXAiOiJKc29uV2ViVG9rZW4iLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJpc3N1c2VyIiwiYXVkIjoiYXVkaWVuY2UiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAiLCJyb2xlX25hbWUiOiJhZG1pbmlzdHJhdG9yLHVzZXIsaHIsbWFuYWdlcixib3NzIiwidXNlcl9pZCI6IjExMjM1OTg4MjE3Mzg2NzUyMDEiLCJyb2xlX2lkIjoiMTEyMzU5ODgxNjczODY3NTIwMSwxMTIzNTk4ODE2NzM4Njc1MjAyLDExMjM1OTg4MTY3Mzg2NzUyMDMsMTEyMzU5ODgxNjczODY3NTIwNCwxMTIzNTk4ODE2NzM4Njc1MjA1IiwidXNlcl9uYW1lIjoiYWRtaW4iLCJuaWNrX25hbWUiOiLnrqHnkIblkZgiLCJ0b2tlbl90eXBlIjoiYWNjZXNzX3Rva2VuIiwiZGVwdF9pZCI6IjExMjM1OTg4MTM3Mzg2NzUyMDEiLCJhY2NvdW50IjoiYWRtaW4iLCJjbGllbnRfaWQiOiJzYWJlciIsImV4cCI6MTkwMjc5MzExMCwibmJmIjoxNTg3NDMzMTEwfQ.7mO1mV6Q0jN7MVTR26zFHzI_a_apTyf9-ie6V-u-E4M"
        "jdtoken": JDLoginModel.default.token ?? ""
    ])
}

let requestClosure = { (endpoint: Endpoint, closure: MoyaProvider.RequestResultClosure) in
    
   do
   {
    var request = try endpoint.urlRequest()
    
    request.timeoutInterval = 30;
    
    if let requestData = request.httpBody
    {
        print("\("request url:")" + "\(request.url!)" + "\n" + "\(request.httpMethod ?? "")" + "\n" + "request parameters:" + "\(String(data: request.httpBody!, encoding: String.Encoding.utf8) ?? "")");
    }
    else
    {
        print("==============================================" + "\n" + "\n" + "\("request url:")" + "\n" + "\(request.url!)" + "\(String(describing: request.httpMethod))" + "\n" + "\n" + "=============================================");
    }
    
    if let headerFields = request.allHTTPHeaderFields
    {
        for item in headerFields
        {
            print("\(item.key)" + ":" + "\(item.value)");
        }
    }
    
    closure(.success(request))
   }
   catch
   {
    print("error:", error)
    
    }
}

let plugin =
NetworkActivityPlugin.init { (changeType, targetType) in
    
    switch (changeType)
    {
    case .began:
        print("==================== 开始请求 ==================")
//        WJBProgressHUD.progressShow()
    case .ended:
//        WJBProgressHUD.progressHidden()
        print("====================  结束  ====================")
    }
}

// -- start -- 新增，还需要测试一下
func cacheSession() -> Session {
    let cache = URLCache(memoryCapacity: 10 * 1024 * 1024, diskCapacity: 100 * 1024 * 1024, directory: nil)
    let configuration = URLSessionConfiguration.default
    configuration.requestCachePolicy = .returnCacheDataElseLoad
    configuration.urlCache = cache
    
    let userSession = Alamofire.Session(configuration: configuration)
    return userSession
}

let provider = MoyaProvider<JDApi>(endpointClosure: endPointClosure, requestClosure: requestClosure, session: cacheSession(), plugins: [plugin])
// -- end --

// 原有的 保留
//let provider = MoyaProvider<JDApi>(endpointClosure: endPointClosure, requestClosure: requestClosure, plugins: [plugin])

// MARK: success(数据 返回) serviceFailure(自定义Error返回) requestFailure(Error 返回)
struct serviceError: Error {
    var statusCode: Int?
    var errorMessage: String?
    
    init(_ httpsCode: Int, _ message: String) {
        self.statusCode = httpsCode
        self.errorMessage = message
    }
}

// 网络请求二次封装
@discardableResult
func JDNetWorkRequest(_ target:JDApi, success: @escaping successClosure, failure: @escaping failClosure, error: @escaping erroeClosure) -> Cancellable?
{
    return provider.request(target, completion: { result in
        
        switch result {
        case .success(let response):
            
            if response.statusCode == 200 {
                // 正常系
                printLog("data内容:\(response)")
                if let jsonString = JDTools.dataChangeToJson(info: response.data) {
                    
                    let commonModel = JDCommonModel.deserialize(from: jsonString, designatedPath: "")
                    if (commonModel?.code ?? "") == "401" {
                        // 未登录
                        JDLoginModel.default.userLogout()
                        UserDefaults.standard.removeObject(forKey: "loginInfo")
                        
                        let loginVC = JDLoginViewController()
                        let navigationLoginVC = UINavigationController(rootViewController: loginVC)
                        JDTools.getKeyWindows()?.rootViewController?.present(navigationLoginVC, animated: true)
                        
                        success("")
                        return
                    }
                    success(jsonString)
                } else {
                    error(response.statusCode)
                }
            } else {
//                printLog("请求异常：\(response.statusCode)")
                // 异常系
                error(response.statusCode)
            }
            
        case .failure(let error):
            failure(error)
        }
    })
}


@discardableResult
func JDDataNetWorkRequest(_ target:JDApi, success: @escaping successDataClosure, failure: @escaping failClosure, error: @escaping erroeClosure) -> Cancellable?
{
    return provider.request(target, completion: { result in
        
        switch result {
        case .success(let response):
            
            if response.statusCode == 200 {
                // 正常系
                success(response.data)
            } else {
                error(response.statusCode)
            }
            
        case .failure(let error):
            failure(error)
        }
    })
}




extension JDTools {
    
    /// 尝试将data类型数据 转换成为 String类型的json字符串
    class func dataChangeToJson(info: Data) -> String? {
        if let jsonData = try? JSONSerialization.jsonObject(with: info, options: []) {
            if let jsonString = JDTools.anyChangeToJson(info: jsonData) {
                return jsonString
            }
        }
        return nil
    }

    /// 尝试将Any类型数据 转换成为 String类型的json字符串
    class func anyChangeToJson(info: Any) -> String? {

        guard JSONSerialization.isValidJSONObject(info) else {
            /// 转换失败
            return nil
        }
        if let jsonData = try? JSONSerialization.data(withJSONObject: info, options: []) {
            let jsonString = String.init(data: jsonData, encoding: .utf8)
            return jsonString
        }
        return nil
    }
}

// 网络请求学习与优化 参考资料
// https://blog.csdn.net/weixin_33901926/article/details/87997648
// https://www.jianshu.com/p/9371c7f6ce6c
//class JDNetworkManager: NSObject {
//
//}


